<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="I2IdZ" id="I2IdZ"><span data-lake-id="u4da81c72" id="u4da81c72">典型回答</span></h1>
  <p data-lake-id="u5fb19bbf" id="u5fb19bbf"><br></p>
  <p data-lake-id="u4d9ba225" id="u4d9ba225"><span data-lake-id="uc439075b" id="uc439075b">想要实现一个单例，首先就是要考虑把构造函数设置成private的，否则的话就可以随时通过构造函数创建对象了，就不是单例了。</span></p>
  <p data-lake-id="ub78fc733" id="ub78fc733"><span data-lake-id="u6216bd96" id="u6216bd96">​</span><br></p>
  <p data-lake-id="u70497b1c" id="u70497b1c"><span data-lake-id="u880e4e8d" id="u880e4e8d">那把构造函数private之后，就还需要提供一个方法，可以初始化单例对象，并且要保证只能初始化一个单例对象。并且需要考虑线程安全的问题。</span></p>
  <p data-lake-id="ue71b963a" id="ue71b963a"><span data-lake-id="ua340e8b1" id="ua340e8b1">​</span><br></p>
  <p data-lake-id="u0ff797d9" id="u0ff797d9"><span data-lake-id="ud732f297" id="ud732f297">具体到写法上，主要有5种。分别是懒汉、饿汉、静态内部类、双重校验锁以及枚举。</span></p>
  <p data-lake-id="u9eda28ed" id="u9eda28ed"><span data-lake-id="u12ef6e2f" id="u12ef6e2f">​</span><br></p>
  <h1 data-lake-id="Hla0l" id="Hla0l"><span data-lake-id="u29126b52" id="u29126b52">扩展知识</span></h1>
  <p data-lake-id="u99712411" id="u99712411"><br></p>
  <h2 data-lake-id="bG24h" id="bG24h"><span data-lake-id="ue559726b" id="ue559726b">懒汉 </span></h2>
  <p data-lake-id="u24ba6015" id="u24ba6015"><br></p>
  <p data-lake-id="u7dd80321" id="u7dd80321"><span data-lake-id="u783b12b1" id="u783b12b1">所谓懒汉，就是在需要的时候才会去创建对象。</span></p>
  <p data-lake-id="u1ecf3f91" id="u1ecf3f91"><span data-lake-id="u76a6a533" id="u76a6a533">​</span><br></p>
  <pre lang="java"><code>
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}  
</code></pre>
  <p data-lake-id="u0b59bb89" id="u0b59bb89"><br></p>
  <p data-lake-id="u1ab5eee7" id="u1ab5eee7"><span data-lake-id="u301ce0f4" id="u301ce0f4">好处就是避免提前创建浪费资源，但是缺点也明显，就是第一创建的时候浪费时间。</span></p>
  <p data-lake-id="u5d0a3952" id="u5d0a3952"><span data-lake-id="u1bcb52ee" id="u1bcb52ee">​</span><br></p>
  <h2 data-lake-id="ynaqx" id="ynaqx"><span data-lake-id="ue857036f" id="ue857036f">饿汉</span></h2>
  <p data-lake-id="u05e03aba" id="u05e03aba"><span data-lake-id="u13af3d3b" id="u13af3d3b">所谓饿汉，就是在类刚一初始化的时候就立即把单例对象创建出来。</span></p>
  <p data-lake-id="uabe4daa8" id="uabe4daa8"><span data-lake-id="u99de7e91" id="u99de7e91">​</span><br></p>
  <pre lang="java"><code>
public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}  
</code></pre>
  <p data-lake-id="u7cf75d7b" id="u7cf75d7b"><br></p>
  <pre lang="java"><code>
public class Singleton {  
    private Singleton instance = null;  
    static {  
    instance = new Singleton();  
    }  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return this.instance;  
    }  
}  
</code></pre>
  <p data-lake-id="u413892fe" id="u413892fe"><span data-lake-id="ue170870f" id="ue170870f">​</span><br></p>
  <p data-lake-id="u9422feea" id="u9422feea"><span data-lake-id="uf13c9104" id="uf13c9104">以上两种都是饿汉模式的具体实现。</span></p>
  <p data-lake-id="u2b95da9f" id="u2b95da9f"><span data-lake-id="u1e8d2a6f" id="u1e8d2a6f">​</span><br></p>
  <h2 data-lake-id="YOa2T" id="YOa2T"><span data-lake-id="ub62cc96b" id="ub62cc96b">静态内部类</span></h2>
  <p data-lake-id="ueec80bf2" id="ueec80bf2"><br></p>
  <pre lang="java"><code>
public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}  
</code></pre>
  <p data-lake-id="u2a69b623" id="u2a69b623"><br></p>
  <h2 data-lake-id="UWsZX" id="UWsZX"><span data-lake-id="uf8fbf76c" id="uf8fbf76c">枚举</span></h2>
  <p data-lake-id="ub66e91bd" id="ub66e91bd"><br></p>
  <pre lang="java"><code>
public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}  
</code></pre>
  <p data-lake-id="uc90c252b" id="uc90c252b"><br></p>
  <p data-lake-id="u981917f1" id="u981917f1"><br></p>
  <h2 data-lake-id="E4CBr" id="E4CBr"><span data-lake-id="u9314b66e" id="u9314b66e">双重校验锁</span></h2>
  <p data-lake-id="ud635b63d" id="ud635b63d"><br></p>
  <pre lang="java"><code>
public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}  
</code></pre>
  <p data-lake-id="ufd7faf8b" id="ufd7faf8b"><br></p>
  <p data-lake-id="u51cae5c9" id="u51cae5c9"><br></p>
  <h1 data-lake-id="LzJI4" id="LzJI4"><span data-lake-id="u4266062d" id="u4266062d">扩展知识</span></h1>
  <p data-lake-id="u64b72fc4" id="u64b72fc4"><br></p>
  <h2 data-lake-id="cgCXF" id="cgCXF"><span data-lake-id="u65577640" id="u65577640">CAS实现单例</span></h2>
  <p data-lake-id="ua59ed135" id="ua59ed135"><br></p>
  <h2 data-lake-id="lm2J2" id="lm2J2"><span data-lake-id="u397d9812" id="u397d9812">如何破坏单例</span></h2>
  <p data-lake-id="u51dda424" id="u51dda424"><br></p>
 </body>
</html>